package org.ptkparty.shared.model;

import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;

import org.datanucleus.api.jpa.annotations.Extension;
import org.ptkparty.server.dao.EMFService;
import org.ptkparty.shared.model.PtkEnum.STATE;

import com.google.appengine.api.users.UserServiceFactory;

@Entity
public class ChampionshipEntity {

	private static final Logger LOGGER = Logger.getLogger(ChampionshipEntity.class.getName());

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
	private String id;

	@Version
	private Integer version;

	@NotNull
	private String name;

	@OneToMany(fetch = FetchType.EAGER)
	@NotNull
	private List<String> users;

	private STATE state;

	private String creator;

	public List<String> getUsers() {
		return users;
	}

	public void setUsers(List<String> users) {
		this.users = users;
	}

	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void persist() {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			this.setCreator(UserEntity.getUser(UserServiceFactory.getUserService().getCurrentUser().getEmail()).getId());
			em.persist(this);
		} finally {
			em.close();
		}
	}

	public void remove() {
		if (this.getId() != null) {
			EntityManager em = EMFService.get().createEntityManager();
			try {
				em.remove(this);
			} catch (Exception e) {
				LOGGER.log(Level.SEVERE, e.getMessage(), e);
			} finally {
				em.close();
			}
		}
	}

	public static ChampionshipEntity findChampionshipEntity(String id) {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			return em.find(ChampionshipEntity.class, id);
		} catch (Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
		} finally {
			em.close();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public static Set<ChampionshipEntity> getAll() {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			Set<ChampionshipEntity> championchips = new java.util.HashSet<ChampionshipEntity>();
			if (UserServiceFactory.getUserService().isUserAdmin()) {
				championchips.addAll(em.createQuery("SELECT c from ChampionshipEntity c").getResultList());

			} else {
				championchips.addAll(em.createQuery("SELECT c from ChampionshipEntity c WHERE c.users IN (:user)") //
						.setParameter("user", UserEntity.getCurrentUser().getId()) //
						.getResultList());

				championchips.addAll(em.createQuery("SELECT c from ChampionshipEntity c WHERE state=:state") //
						.setParameter("state", STATE.PUBLIC) //
						.getResultList());
			}
			championchips.size();
			return championchips;
		} catch (Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
		} finally {
			em.close();
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public static List<ChampionshipEntity> getAllForAdmin() {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			List<ChampionshipEntity> championchips;
			if (UserServiceFactory.getUserService().isUserAdmin()) {
				championchips = em.createQuery("SELECT c from ChampionshipEntity c").getResultList();
			} else {
				championchips = em.createQuery("SELECT c from ChampionshipEntity c WHERE c.creator=:user") //
						.setParameter("user", UserEntity.getUser(UserServiceFactory.getUserService().getCurrentUser().getEmail()).getId()) //
						.getResultList();
			}
			championchips.size();
			return championchips;
		} catch (Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
		} finally {
			em.close();
		}
		return null;
	}

	public static void save(List<ChampionshipEntity> championships) {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			String userId = UserEntity.getUser(UserServiceFactory.getUserService().getCurrentUser().getEmail()).getId();
			for (ChampionshipEntity championship : championships) {
				if (championship.getCreator() == null) {
					championship.setCreator(userId);
				}
				if (championship.getId() == null) {
					em.persist(championship);
				} else {
					em.merge(championship);
				}
			}
		} catch (Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
		} finally {
			em.close();
		}
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getCreator() {
		return creator;
	}

	public void setCreator(String creator) {
		this.creator = creator;
	}

	public STATE getState() {
		return state;
	}

	public void setState(STATE state) {
		this.state = state;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj != null && this != null) {
			if (obj instanceof ChampionshipEntity) {
				if (((ChampionshipEntity) obj).getId() != null && this.id != null) {
					return ((ChampionshipEntity) obj).getId().equals(this.id);
				}
			}
		}
		return false;
	}

}
